﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kokomo.Environment.Services;
using System.Windows.Media;
using System.Reflection;
using System.Windows.Media.Imaging;

namespace Kokomo.Environment.Hosting.Services
{
	/// <summary>
	/// Manages a list of images.
	/// </summary>
	/// <remarks>
	/// Add images to the list using <see cref="AddImage"/> or <see cref="AddImageResource"/>
	/// </remarks>
	public class ImageManager : IImageProvider
	{
		/// <summary>
		/// Initializes a new instance of <see cref="ImageManager"/>.
		/// </summary>
		public ImageManager(Assembly assembly = null)
		{
			this.Assembly = assembly;
			this._images = new Dictionary<string, ImageSource>();
		}

		public Assembly Assembly { get; private set; }

		/// <summary>
		/// Adds an image resource to the list.
		/// </summary>
		/// <param name="key">The key that identifies the image within the list.</param>
		/// <param name="resourcePath">The path of the resource within <paramref name="assembly"/>.</param>
		/// <param name="assembly">The <see cref="Assembly"/> containing the resource.</param>
		/// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
		/// <exception cref="ArgumentNullException"><paramref name="assembly"/> is <c>null</c>.</exception>
		/// <exception cref="ArgumentNullException"><paramref name="resourcePath"/> is <c>null</c>.</exception>
		/// <remarks>
		/// This method builds a pack:// URI using <paramref name="assembly"/> and
		/// <paramref name="resourcePath"/>.
		/// </remarks>
		public void AddImageResource(string key,
			string resourcePath,
			Assembly assembly = null
			)
		{
			if (assembly == null) assembly = this.Assembly;
			if (key == null) throw new ArgumentNullException("key");
			if (resourcePath == null) throw new ArgumentNullException("resourcePath");

			if (assembly == null) throw new ArgumentNullException("assembly");

			Uri baseUri = new Uri(string.Format("pack://application:,,,/{0};component/", assembly.GetName().Name));
			Uri resourceUri = new Uri(baseUri, resourcePath);

			ImageSource image = new BitmapImage(resourceUri);

			this._images[key] = image;
		}
		/// <summary>
		/// Adds an image to the list.
		/// </summary>
		/// <param name="key">The key that identifies the image within the list.</param>
		/// <param name="image">The <see cref="ImageSource"/> to add.</param>
		/// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
		/// <exception cref="ArgumentNullException"><paramref name="image"/> is <c>null</c>.</exception>
		public void AddImage(string key, ImageSource image)
		{
			if (key == null) throw new ArgumentNullException("key");
			if (image == null) throw new ArgumentNullException("image");

			this._images[key] = image;
		}

		private Dictionary<string, ImageSource> _images;

		/// <summary>
		/// Gets the image with the specified key.
		/// </summary>
		/// <param name="key">The key identifying the image.</param>
		/// <returns>The requested image, if available; otherwise, <c>null</c>.</returns>
		/// <exception cref="ArgumentNullException"><paramref name="key"/> is <c>null</c>.</exception>
		public System.Windows.Media.ImageSource GetImage(string key)
		{
			if (key == null) throw new ArgumentNullException("key");

			ImageSource image;
			this._images.TryGetValue(key, out image);

			return image;
		}
	}
}
